/**
 * JAVACC DEMO 1.0
 */

package com.apache.uct.common;

import java.io.*;
import java.net.URL;
import java.util.*;

import org.apache.commons.io.IOUtils;

import com.apache.tools.ConfigUtil;

/**
 * description:  获取配置信息工具类
 *
 * @author  创建时间：2016-7-23
 */
public class ToolsUtil {

	private Map<String, Long> lastUpateTime = new HashMap<String, Long>();//最后修改时间

	private Map<String, Map<String, String>> constant = new HashMap<String, Map<String, String>>();//存放系统配置参数

	private static ToolsUtil instance;

	private String filePath = "";

	public static final String BLANK = "";

	public static final String NULL = "null";

	private ToolsUtil() {
		filePath = getClassLoaderPath() + "config/";
	}

	public static synchronized ToolsUtil getInstance() {
		if (null == instance) {
			instance = new ToolsUtil();
		}
		return instance;
	}

	/**
	 * description: 加载配置文件
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private String initConfig(String key, String fileName) {
		synchronized (this) {
			boolean mark = null == this.constant.get(fileName);
			Properties prop = ConfigUtil.getInstance().getConfigForCache("", fileName, mark);
			if (null == prop || prop.isEmpty()) {//不启用缓存
				if (filePath.indexOf(".jar") != -1) {
					if (isEmpty(constant.get(fileName))) {
						prop = getProperties(filePath, fileName);
					}
				} else {
					File oldfile = new File(filePath + fileName);
					long lastModletime = oldfile.lastModified();
					Long lastTime = lastUpateTime.get(fileName);
					if (null == lastTime || lastTime < lastModletime) {//有更新从新加载
						lastUpateTime.put(fileName, lastModletime);
						prop = getProperties(filePath + fileName);
					}
				}
			}
			if (!isEmpty(prop) && !prop.isEmpty()) {//有更新从新加载
				Map<String, String> map = new HashMap<String, String>((Map) prop);
				Set propertySet = map.entrySet();
				Map<String, String> param = new HashMap<String, String>();
				for (Object o : propertySet) {
					Map.Entry entry = (Map.Entry) o;
					param.put(entry.getKey().toString(), entry.getValue().toString());
				}
				constant.put(fileName, param);
			}
		}
		if (isNull(key)) {
			return "";
		} else {
			if (isEmpty(constant.get(fileName)))
				return "";
			return isNull(constant.get(fileName).get(key), "");
		}
	}

	/**
	 * 获取property文件的属性值
	 *
	 * @param key
	 * @return
	 */
	public String getValueByKey(String propFileName, String key) {
		return initConfig(key, propFileName);
	}

	/**
	 * 读取本地指定配置文件的指定key
	 *
	 * @param fileName 配置文件名称，如config.properties
	 * @param key
	 * @return
	 */
	public String getLocalByKey(String fileName, String key) {
		File oldfile = new File(filePath + fileName);
		long lastModletime = oldfile.lastModified();
		Long lastTime = lastUpateTime.get(fileName);
		if (null == lastTime || lastTime < lastModletime) {//有更新从新加载
			lastUpateTime.put(fileName, lastModletime);
			Properties prop = getProperties(filePath + fileName);
			if (isEmpty(prop))
				return "";
			Map<String, String> map = new HashMap<String, String>((Map) prop);
			Set propertySet = map.entrySet();
			Map<String, String> param = new HashMap<String, String>();
			for (Object o : propertySet) {
				Map.Entry entry = (Map.Entry) o;
				param.put(entry.getKey().toString(), entry.getValue().toString());
			}
			constant.put(fileName, param);
		}
		if (isNull(key)) {
			return "";
		} else {
			if (isEmpty(constant.get(fileName)))
				return "";
			return isNull(constant.get(fileName).get(key), "");
		}
	}

	public String getValueByKey(String propFileName, String key, String charset) {
		try {
			charset = isNull(charset, "UTF-8");
			String result = new String(initConfig(key, propFileName).getBytes("iso8859-1"), charset);
			return result;
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * 获取property文件的属性值
	 *
	 * @param key
	 * @return
	 */
	public String getValueByKey(String key) {
		String result = initConfig(key, ConfigUtil.UNITY_CINFIG);
		return result;
	}

	/**
	 * 获取property文件的属性值
	 *
	 * @param key
	 * @return
	 */
	public String getClientValueByKey(String key) {
		String result = initConfig(key, ConfigUtil.CLIENT_CINFIG);
		return result;
	}

	/**
	 * 获取某个配置文件下的所有配置信息
	 *
	 * @return
	 */
	public Map<String, String> getAllProperty(String propFileName) {
		initConfig("", propFileName);
		return constant.get(propFileName);
	}

	/**
	 * 获取Poperties文件
	 *
	 * @param filePath 资源文件路径
	 * @return 返回Poperties中文件属性
	 */
	public Properties getProperties(String filePath) {
		Properties prop = null;
		FileInputStream fileInput = null;
		try {
			File file = new File(filePath);
			if (file.exists()) {// 判断文件夹是否存在
				prop = new Properties();
				fileInput = new FileInputStream(filePath);
				prop.load(fileInput);
			}
		} catch (IOException e) {
			System.out.println("文件(" + filePath + ")读取失败 key=" + e.getMessage());
		} finally {
			IOUtils.closeQuietly(fileInput);
		}
		return prop;
	}

	public Properties getProperties(String filePath, String fileName) {
		Properties prop = null;
		FileInputStream fileInput = null;
		InputStream stream = null;
		try {
			if (filePath.indexOf(".jar") != -1) {
				stream = ToolsUtil.class.getClassLoader().getResourceAsStream("config/" + fileName);
				prop = new Properties();
				prop.load(stream);
			} else {
				File file = new File(filePath + fileName);
				if (file.exists()) {// 判断文件夹是否存在
					prop = new Properties();
					fileInput = new FileInputStream(filePath + fileName);
					prop.load(fileInput);
				}
			}
		} catch (Exception e) {
			System.out.println("文件(" + fileName + ")读取失败 key=" + e.getMessage());
		} finally {
			IOUtils.closeQuietly(fileInput);
			IOUtils.closeQuietly(stream);
		}
		return prop;
	}

	/**
	 * 判断对象数组是否为空
	 *
	 * @param object 对象数组
	 * @return 如果object为空返回true，不为空返回false
	 */
	public static boolean isNull(Object[] object) {
		if (object == null || object.length == 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 判断一个字符串是否为空,为空则返回默认字符串
	 *
	 * @param str 传入的字符串
	 * @param defaultStr 默认字符串
	 * @return 如果str为空返回defaultStr，不为空返回str
	 */
	public static String isNull(String str, String defaultStr) {
		if (isNull(str))
			return defaultStr;
		return str;
	}

	/**
	 * 判断一个字符串是否为空
	 *
	 * @param str 传入的字符串
	 * @return 如果str为空返回true，不为空返回false
	 */
	public static boolean isNull(String str) {
		if (str == null) {
			return true;
		}
		str = str.trim();
		if ((str.equals(NULL)) || (str.equals(BLANK))) {
			return true;
		}
		return false;
	}

	/**
	 * 判断字符串不能为空
	 *
	 * @param str 传入的字符串
	 * @return 如果str不为空返回true，为空返回false
	 */
	public static boolean isNotNull(String str) {
		return !isNull(str);
	}

	/**
	 * 判断对象是否为空
	 *
	 * @param obj 传入的对象
	 * @return 如果obj为空返回true，不为空返回false
	 */
	public static boolean isEmpty(Object obj) {
		return obj == null;
	}

	/**
	 * 判断一个list集合是否为空
	 *
	 * @param list 传入的list
	 * @return 如果list为空或者长度为0返回true，不为空返回false
	 */
	public static boolean isEmpty(List list) { //
		return list == null || list.size() == 0;
	}

	/**
	 * 判断一个list集合是否为空
	 *
	 * @param collection 传入的集合
	 * @return 如果collection为空或者长度为0返回true，不为空返回false
	 */
	public static boolean isEmpty(Collection collection) { //
		return collection == null || collection.isEmpty();
	}

	/**
	 * @return 返回classes的绝对路径。
	 */
	public static String getClassLoaderPath() {
		String path = "";
		URL classLoaderUrl = Thread.currentThread().getContextClassLoader().getResource("");
		if (isEmpty(classLoaderUrl)) {
			path = Thread.currentThread().getContextClassLoader().getResource("/").getPath();//tomcat/weblogic
		} else {
			path = classLoaderUrl.getPath();
		}
		if (isNotNull(path)) {
			if (path.startsWith(File.separator) || path.startsWith("/")) {
				String systemType = getSystemType();
				if ("windows".equals(systemType))
					path = path.substring(1);
			}
			if (!path.endsWith(File.separator) && !path.endsWith("/"))
				path += "/";
		}
		return path;
	}

	/**
	 * 获取操作系统类型
	 *
	 * @return 返回操作系统类型
	 */
	public static String getSystemType() {
		String result = "windows";
		if (System.getProperty("os.name").equals("Linux")) {
			result = "linux";
		} else if ("Mac OS X".equals(System.getProperty("os.name"))) {
			result = "Mac OS X";
		}
		return result;
	}

}
